<script setup lang="ts">
import type { AppMenu } from '@/apis/system/appMenuApi'

import type { DataAction } from '@/components/DataForm/types'
import { FullScreen, Hide, Refresh, View } from '@element-plus/icons-vue'
import { Icon } from '@iconify/vue'
import { storeToRefs } from 'pinia'
import { onMounted, reactive, ref, watch } from 'vue'
import { CommonStates } from '@/apis/common/commonApi'
import { appMenuApi, AppMenuTypes } from '@/apis/system/appMenuApi'
import { doDataAction } from '@/components/DataForm/types'
import { useEditFormDrawer } from '@/components/DataForm/useEditFormDrawer'
import { useTable } from '@/components/DataPage/useTable'
import BaseCard from '@/layouts/BaseCard.vue'
import { useDictStore } from '@/stores/dictStore'
import { hasAuth } from '@/utils/authUtil'
import AppApiSelect from '../components/AppApiSelect.vue'

const {
  editFormData,
  openEditForm,
  EditFormDrawer,
} = useEditFormDrawer<AppMenu>({
  editFields: [
    { name: 'type', title: '类型', edit: data => data.id === undefined, require: true, options: [...AppMenuTypes], editType: 'button' },
    { name: 'moduleName', title: '模块', edit: data => data.id === undefined, require: true, dict: { dictCode: 'MODULE', dictFilter: dict => (dict.customData?.type === 'BIZ') }, checkStrictly: true, change: moduleNameChange },
    { name: 'name', title: '名称', require: true, maxLength: 32 },
    { name: 'code', title: '权限编码', maxLength: 32 },
    { name: 'path', title: '页面路径', maxLength: 128, show: data => data.type === 'MENU' },
    { name: 'priority', title: '优先级', require: true, type: 'number', editType: 'number' },
    { name: 'state', title: '状态', require: true, options: [...CommonStates], editType: 'button' },
    { name: 'visible', title: '可见', type: 'boolean', show: data => data.type !== 'FUNCTION' },
    { name: 'icon', title: '图标' },
    { name: 'apis', title: '应用接口', show: data => data.appType !== undefined && data.moduleName !== undefined },
  ],
})

const {
  tableData,
  Table,
  TableFieldFilterButton,
} = useTable<undefined, AppMenu>({
  autoQuery: false,
  tableFields: [
    { title: 'ID', name: 'id', width: 80, columnType: 'KEY', show: false },
    { title: '菜单', name: 'name', width: 180, columnType: 'MAIN' },
    { title: '模块', name: 'moduleName', width: 180, dict: 'MODULE' },
    { title: '类型', name: 'type', width: 90, options: [...AppMenuTypes] },
    { title: '状态', name: 'state', width: 90, options: [...CommonStates] },
    { title: '是否可见', name: 'visible', width: 80, align: 'center' },
    { title: '路径', name: 'path', width: 120 },
    { title: '编码', name: 'code', width: 120 },
    { title: '优先级', name: 'priority', width: 100, align: 'center' },
  ],
})

const appType = ref<string>()
const expandRowKeys = ref<string[]>([])

async function loadTreeData() {
  if (appType.value) {
    const list = await appMenuApi.queryTree(appType.value)
    tableData.value = list.filter(m => m !== undefined)
  }
}

function setExpandRowKeys(children: AppMenu[]) {
  children.forEach((child) => {
    if (child.children && child.children.filter(c => c.type === 'MENU').length > 0) {
      expandRowKeys.value.push(`${child.id}`)
      setExpandRowKeys(child.children)
    }
  })
}

const dictStore = useDictStore()
const { dictMap } = storeToRefs(dictStore)
onMounted(async () => {
  await dictStore.loadDict('ENUM_APP_TYPE')
  if (dictMap.value.ENUM_APP_TYPE && dictMap.value.ENUM_APP_TYPE.length > 0) {
    appType.value = dictMap.value.ENUM_APP_TYPE[0].dictCode
  }
})

watch(() => appType.value, async () => {
  await loadTreeData()
  if (tableData.value && Array.isArray(tableData.value)) {
    setExpandRowKeys(tableData.value)
  }
})

const actions = reactive<Record<string, DataAction>>({
  create: {
    label: '新增',
    type: 'primary',
    authCode: 'system:app:menu:create',
    click: () => openEditForm('新增', {
      appType: appType.value!,
      type: 'MENU',
      state: 'ENABLE',
      parentId: 0,
      visible: true,
      priority: (Array.isArray (tableData.value) ? tableData.value.length : 0) + 1,
    }, appMenuApi.create),
  },
  modify: {
    label: '编辑',
    type: 'primary',
    authCode: 'system:app:menu:modify',
    click: onEdit,
  },
  changeState: {
    label: row => row.state === 'ENABLE' ? '禁用' : '启用',
    type: 'warning',
    authCode: 'system:app:menu:modify',
    confirm: row => `是否${row.state === 'ENABLE' ? '禁用' : '启用'}应用菜单`,
    click: data => appMenuApi.modify({ id: data.id, state: data.state === 'ENABLE' ? 'DISABLE' : 'ENABLE' }),
    success: () => loadTreeData(),
    message: true,
  },
  remove: {
    label: '删除',
    type: 'danger',
    authCode: 'system:app:menu:remove',
    confirm: '删除不可恢复，请谨慎确认',
    click: data => appMenuApi.remove(data.id),
    success: () => loadTreeData(),
    message: true,
  },
  addChild: {
    label: '添加下级',
    type: 'primary',
    authCode: 'system:app:menu:create',
    show: row => row.type !== 'FUNCTION',
    click: parent => openEditForm('新增', {
      appType: appType.value!,
      type: 'MENU',
      state: 'ENABLE',
      parentId: parent.id,
      visible: true,
      priority: (parent.children?.length ?? 0) + 1,

    }, appMenuApi.create),
  },
  addChildFun: {
    label: '添加功能',
    type: 'primary',
    authCode: 'system:app:menu:create',
    show: row => row.type !== 'FUNCTION',
    click: parent => openEditForm('新增', {
      appType: appType.value!,
      type: 'FUNCTION',
      moduleName: parent.moduleName,
      code: parent.code,
      state: 'ENABLE',
      parentId: parent.id,
      visible: true,
      priority: (parent.children?.length ?? 0) + 1,

    }, appMenuApi.create),
  },
  changeVisible: {
    label: row => row.visible ? '显示' : '隐藏',
    show: () => false,
    type: 'info',
    authCode: 'system:app:menu:modify',
    click: data => appMenuApi.modify({ id: data.id, visible: data.visible }),
    success: () => loadTreeData(),
    message: true,
  },
  changePriority: {
    label: '调整优先级',
    show: () => false,
    type: 'info',
    authCode: 'system:app:menu:modify',
    click: data => appMenuApi.modify({ id: data.id, priority: data.priority }),
    success: () => loadTreeData(),
    message: true,
  },
})

async function onEdit(row: AppMenu) {
  openEditForm('编辑', await appMenuApi.findDetail(row.id!), appMenuApi.modify)
}

function moduleNameChange(moduleName: string) {
  if (editFormData.value && moduleName) {
    const dict = dictStore.getDict('MODULE', moduleName)
    const data: Partial<AppMenu> = { ...editFormData.value, children: [] }
    if (dict) {
      data.name = dict.dictName
      data.code = dict.dictCode?.replace('.', ':')
      if (editFormData.value.type === 'MENU') {
        data.path = `/${dict.dictCode?.replace('.', '/')}`
      }
    }
    editFormData.value = data
  }
}

function onClickRow(row: AppMenu) {
  if (row.type === 'MENU') {
    if (expandRowKeys.value.includes(`${row.id}`)) {
      expandRowKeys.value = expandRowKeys.value.filter(key => key !== `${row.id}`)
    }
    else {
      expandRowKeys.value.push(`${row.id}`)
    }
  }
}
</script>

<template>
  <BaseCard>
    <template #title>
      <el-segmented
        v-model="appType"
        size="large"
        :options="dictMap.ENUM_APP_TYPE"
        :props="{ value: 'dictCode', label: 'dictName' }"
      />
    </template>

    <template #buttons>
      <!-- 表格按钮 -->
      <data-button :action="actions.create" />

      <el-button :icon="Refresh" circle @click="loadTreeData()" />
      <el-button :icon="FullScreen" circle />
      <TableFieldFilterButton />
    </template>
    <!-- 数据表格 -->
    <Table
      :expand-row-keys="expandRowKeys"
      :row-actions="[
        actions.addChild,
        actions.addChildFun,
        actions.modify,
        actions.changeState,
        actions.remove,
      ]"
      @change="loadTreeData"
      @row-click="onClickRow"
    >
      <template #name="{ row }">
        <span class="text-active">
          <Icon v-if="row.icon" :icon="row.icon" :inline="true" /> {{ row.name }}
        </span>
      </template>
      <template #visible="{ row }">
        <el-switch
          v-model="row.visible"
          :disabled="!hasAuth('system:app:menu:modify')"
          :active-action-icon="View"
          :inactive-action-icon="Hide"
          @click.stop
          @change="doDataAction(row, actions.changeVisible)"
        />
      </template>
      <template #priority="{ row }">
        <el-input-number
          v-model="row.priority"
          :disabled="!hasAuth('system:app:menu:modify')"
          :min="1"
          :max="99"
          @click.stop
          @change="doDataAction(row, actions.changePriority)"
        />
      </template>
    </Table>
  </BaseCard>

  <!-- 数据编辑 -->
  <EditFormDrawer @success="(_:string, data:AppMenu) => { loadTreeData(); expandRowKeys.push(`${data.parentId}`) }">
    <template #icon>
      <icon-select v-model="editFormData.icon" />
    </template>
    <template #apis>
      <AppApiSelect
        v-model="editFormData.apis"
        :app-type="editFormData.appType!"
        :module="editFormData.moduleName!"
      />
    </template>
  </EditFormDrawer>
</template>
